//
// Created by jasonzhuang on 15-12-1.
//

#include <math.h>

#include <algorithm>
#include <ctime>
#include <vector>

#include "SpreadCalc.h"

void calculateEMA(const EMARequest& request, EMAResponse& response) {
  int length = request.series.size();
  int min_l = std::min(length, request.N);
  if (min_l == 0) return;
  double alpha = 2.0 / (request.N + 1);
  /*
  response.means[0] = request.series[0];
  response.stds[0] = 0;*/
  for (int i = 0; i < min_l; ++i) {
    // alpha = 2.0 / (i + 1 + 1);
    if (i == 0) {
      response.means[i] = request.series[i];
      response.stds[i] = 0;
    } else
      response.means[i] =
          alpha * request.series[i] + (1 - alpha) * response.means[i - 1];
    // response.means[i] = alpha * sum / (i+1) + (1 - alpha) *
    // response.means[i-1];

    double sum_variance = 0.0;
    double u = 0.0;
    double sum_ema = 0.0;
    for (int j = 0; j <= i; ++j) {
      sum_ema += response.means[j];
    }
    u = sum_ema / (i + 1);
    for (int j = 0; j <= i; ++j) {
      sum_variance += (response.means[j] - u) * (response.means[j] - u);
    }
    response.stds[i] = sqrt(sum_variance / (i + 1));
  }
  for (int i = min_l; i < length; ++i) {
    if (i == 0) {
      response.means[i] = request.series[i];
      response.stds[i] = 0;
    } else
      response.means[i] =
          alpha * request.series[i] + (1 - alpha) * response.means[i - 1];
    // response.means[i] = alpha * sum / min_l + (1 - alpha) *
    // response.means[i-1];

    double sum_variance = 0.0;
    double u = 0.0;
    double sum_ema = 0.0;
    for (int j = 0; j < min_l; ++j) {
      sum_ema += response.means[i - j];
    }
    u = sum_ema / min_l;
    for (int j = 0; j < min_l; ++j) {
      sum_variance += (response.means[i - j] - u) * (response.means[i - j] - u);
    }
    response.stds[i] = sqrt(sum_variance / min_l);
  }
}